﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Clipping.Infrastructure.Models;
using System.Web;
using System.Text.RegularExpressions;

namespace Clipping.Utils.SearchEngines
{
    public class YoudaoNews : ISearchEngine
    {


        private Encoding _urlEncoding = Encoding.UTF8;
        private Encoding _contentEncoding = Encoding.UTF8;
        public void Parse(Uri url, string html, out List<News> news, out string nextPageUrl)
        {
            parse(html, out news, out nextPageUrl);
            if (!string.IsNullOrEmpty(nextPageUrl))
                nextPageUrl = constructAbsoluteUrl(url, nextPageUrl).OriginalString;
            if (news != null)
            {
                foreach (var n in news)
                {
                    if (!string.IsNullOrEmpty(n.SameNewsUrl))
                        n.SameNewsUrl = constructAbsoluteUrl(url, n.SameNewsUrl).OriginalString;
                }
            }
        }

        public Uri ConstructUrl(SearchObject searchObj)
        {
            return constructUrl(searchObj);
        }
        public void Search(Infrastructure.Models.SearchObject searchObj, IHtmlDownload downloader, out List<Infrastructure.Models.News> news, out string nextPageUrl)
        {
            var url = constructUrl(searchObj);
            string html = downloader.GetHtml(url, Encoding.UTF8);
            parse(html, out news, out nextPageUrl);
            if (!string.IsNullOrEmpty(nextPageUrl))
                nextPageUrl = constructAbsoluteUrl(url, nextPageUrl).OriginalString;
            if (news != null)
            {
                foreach (var n in news)
                {
                    if (!string.IsNullOrEmpty(n.SameNewsUrl))
                        n.SameNewsUrl = constructAbsoluteUrl(url, n.SameNewsUrl).OriginalString;
                }
            }
        }


        #region 私有方法


        private Uri constructUrl(Infrastructure.Models.SearchObject searchObj)
        {
            return new Uri(string.Format("{0}{1}{2}", "http://news.youdao.com/search?q=", HttpUtility.UrlEncode(searchObj.Keyword, this._urlEncoding), "&s=pdate&tr=no_range&keyfrom=search.bytime"));
        }
        private Uri constructAbsoluteUrl(Uri baseUri, string url)
        {
            return UriHelper.ConstructAbsoluteUrl(baseUri, url);
        }



        protected void parse(string html, out List<Infrastructure.Models.News> news, out string nextPageUrl)
        {
            news = new List<News>();
            nextPageUrl = null;
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            var liNav = doc.CreateNavigator();

            var divContentSearch = liNav.Select("//ul[@id='results']//li");
            while (divContentSearch.MoveNext())
            {
                News n = new News();

                var li = divContentSearch.Current;

                //取标题和链接
                var linkNode = li.SelectSingleNode("child::h3/a");
                if (linkNode == null)
                {
                    linkNode = li.SelectSingleNode("child::a");
                }
                if (linkNode != null)
                {
                    n.Title = linkNode.Value;
                    n.Title = System.Web.HttpUtility.HtmlDecode(n.Title);
                    n.Url = linkNode.GetAttribute("href", "");
                    if (!string.IsNullOrEmpty(n.Url))
                        n.Url = System.Web.HttpUtility.HtmlDecode(n.Url);
                }

                //取时间
                var dtAndMediaNode = li.SelectSingleNode("descendant::span[@class='green stat']");
              
               
                if (dtAndMediaNode != null)
                {
                  

                    string str = dtAndMediaNode.Value;
                    if (!string.IsNullOrEmpty(str))
                    {
                        str = System.Web.HttpUtility.HtmlDecode(str);
                        var match = Regex.Match(str, @"(\d+)(小时|分钟)前", RegexOptions.IgnoreCase);


                        if (match.Success)
                        {
                            int v = int.Parse(match.Groups[1].Value);
                            if (match.Groups[2].Value == "小时")
                            {
                                n.PubDate = DateTime.Now.AddHours(0 - v).ToString("yyyy-MM-dd");
                            }
                            else
                            {
                                n.PubDate = DateTime.Now.AddMinutes(0 - v).ToString("yyyy-MM-dd");
                            }
                        
                        }


                        var m = Regex.Match(str, @"\s", RegexOptions.None);
                        if (m.Success)
                        {
                            int index = m.Index;
                               if (index > 0)
                                n.Media = str.Substring(0, index+1);
                        }
                    }


                }
                //取摘要
                var summaryNode = li.SelectSingleNode("child::p");
                if (summaryNode != null)
                {
                    n.Summary = summaryNode.Value;
                }

                var sameNewsNode = li.SelectSingleNode("descendant::span[@class='s']/a");
                if (sameNewsNode != null)
                {
                    n.SameNewsUrl = sameNewsNode.GetAttribute("href", "");
                }
                news.Add(n);
            }


            var nextPageNode = liNav.SelectSingleNode("//div[@class='c-pages']/a[contains(.,'下一页')]");
            if (nextPageNode != null)
            {
                nextPageUrl = nextPageNode.GetAttribute("href", "");
                if (!string.IsNullOrEmpty(nextPageUrl))
                    nextPageUrl = System.Web.HttpUtility.HtmlDecode(nextPageUrl);
            }

        }

        #endregion


        #region 属性

        public string Name
        {
            get { return "有道新闻搜索"; }
        }
        public Encoding ContentEncoding
        {
            get { return _contentEncoding; }
        }
        #endregion


       
    }
}
